import type { CSSProperties, SVGProps } from 'react';

import { Icon } from '@iconify/react';

/**
 * SvgIcon 组件属性类型定义
 * @property className - 自定义样式类名
 * @property icon - iconify 图标名称（如 'mdi:home'）
 * @property localIcon - 本地 svg 图标名称（如 'user'）
 * @property style - 行内样式
 */
export interface SvgIconProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
	readonly className?: string;
	readonly icon?: string;
	readonly localIcon?: string;
	readonly style?: CSSProperties;
}

/**
 * 默认本地图标名称（找不到时兜底）
 */
const defaultLocalIcon = 'no-icon';

// 从环境变量获取本地 SVG 前缀
const { VITE_ICON_LOCAL_PREFIX: prefix } = import.meta.env;

/**
 * 生成本地 SVG 图标的 symbolId
 * @param localIcon - 本地 svg 图标名称
 * @returns symbolId 字符串（如 #local-user）
 */
function symbolId(localIcon: string = defaultLocalIcon): string {
	const iconName = localIcon || defaultLocalIcon;
	return `#${prefix}-${iconName}`;
}

/**
 * SvgIcon 通用图标组件
 *
 * 支持 iconify 图标和本地 svg 图标。
 * - 若同时传入 icon 和 localIcon，优先渲染本地 svg 图标。
 * - 其余属性（如 className、style）会透传到 svg 或 Icon 组件。
 *
 * @param props - 组件属性，详见 SvgIconProps
 * @returns React 元素
 */
const SvgIcon = ({ icon, localIcon, ...props }: SvgIconProps) => {
	// 过滤出仅属于 IconifyIconProps 的属性，防止类型冲突
	const iconifyProps: Record<string, unknown> = {};
	const iconifyAllowedKeys = [
		'icon',
		'color',
		'width',
		'height',
		'rotate',
		'hFlip',
		'vFlip',
		'inline',
		'flip',
		'style',
		'className',
		'onLoad',
		'tabIndex',
		'ariaHidden',
		'ariaLabel',
		'title',
		'ref'
	];
	Object.keys(props as Record<string, unknown>).forEach(key => {
		if (iconifyAllowedKeys.includes(key)) {
			iconifyProps[key] = (props as Record<string, unknown>)[key];
		}
	});
	if (localIcon || !icon) {
		// 优先渲染本地 svg 图标
		return (
			<svg height="1em" width="1em" {...props} aria-hidden="true">
				{/* 通过 <use> 标签引用 symbolId，支持多色和样式继承 */}
				<use fill="currentColor" href={symbolId(localIcon)} />
			</svg>
		);
	} else if (icon?.startsWith('icon-')) {
		// 若 icon 名称以 'icon-' 开头，则渲染 IconFont 组件
		return <IconFont type={icon} {...iconifyProps} />;
	} else {
		// 否则渲染 iconify 图标，props 只传递允许的属性
		return <Icon icon={icon} {...iconifyProps} />;
	}
};

export default SvgIcon;
